package com.nuatar.meibi.scoll;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import com.nuatar.meibi.R;
import com.nuatar.meibi.pubvar.Configer;
import com.nuatar.meibi.pubvar.ImagePair;
import com.nuatar.meibi.pubvar.PhoneMaster;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.View;

public class MyXZ extends View {
	private final Rect SrcRect = new Rect();
	private final Rect DstRect = new Rect();
	private float RecentZoom = 1;
	private float Zoom = 1;
	private Point Pan = new Point(0, 0);
	private Bitmap mBitmap;
	Context ctx;
	ImageGetter ig;

	public MyXZ(Context context, AttributeSet attrs) {
		super(context, attrs);
		ctx=context;
	}
	public MyXZ(Context context) {
		super(context);
		ctx=context;
	
	}
	public void setImageGetter(ImageGetter igs){
		ig=igs;
	}
	@Override
	protected void onDraw(Canvas canvas) {
		if (mBitmap != null) {
			UpdateRZ();
			PaintFlagsDrawFilter pfd = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
			canvas.setDrawFilter(pfd);
			canvas.drawBitmap(mBitmap, SrcRect, DstRect, null);
		}
	}
	public void recycleImage(){
		if(mBitmap!=null){
			mBitmap.recycle();
		}
		
	}
	private void UpdateRZ() {
		if (mBitmap != null) {
			float bw = mBitmap.getWidth();
			float bh = mBitmap.getHeight();
			float Sw = getWidth();
			float Sh = getHeight();
			if (bw * (Sh / bh) <= Sw) {
				RecentZoom = Sh / bh;
			}
			if (bh * (Sw / bw) <= Sh) {
				RecentZoom = Sw / bw;
			}
			int DesX = (int) Math.min(mBitmap.getWidth() * RecentZoom
					* getZoom(), getWidth());
			int DesY = (int) Math.min(mBitmap.getHeight() * RecentZoom
					* getZoom(), getHeight());
			int ResX = Math.round(DesX / RecentZoom / getZoom());
			int ResY = Math.round(DesY / RecentZoom / getZoom());
			if (Pan.x + (bw - ResX) / 2 < 0) {
				Pan.x = -((int) (bw - ResX) / 2);
			}
			if (Pan.y + (bh - ResY) / 2 < 0) {
				Pan.y = -((int) ((bh - ResY) / 2));
			}
			if (ResX + (Pan.x + (bw - ResX) / 2) > bw) {
				Pan.x = (int) ((bw - ResX) / 2);
			}
			if (ResY + Pan.y + (bh - ResY) / 2 > bh) {
				Pan.y = (int) ((bh - ResY) / 2);
			}
			SrcRect.left = (int) (Pan.x + (bw - ResX) / 2);
			SrcRect.top = (int) (Pan.y + (bh - ResY) / 2);
			SrcRect.right = (int) (ResX + (Pan.x + (bw - ResX) / 2));
			SrcRect.bottom = (int) (ResY + Pan.y + (bh - ResY) / 2);
			DstRect.left = (getWidth() - DesX) / 2;
			DstRect.right = (getWidth() - DesX) / 2 + DesX;
			DstRect.top = (getHeight() - DesY) / 2;
			DstRect.bottom = (getHeight() - DesY) / 2 + DesY;
		}
	}

	public void setPan(int x, int y) {
		
			Pan.x += x / getZoom() / RecentZoom;
			Pan.y += y / getZoom() / RecentZoom;
		
		update();
	}

	public Point getPan() {
		return Pan;
	}

	public void update() {
		UpdateRZ();
		invalidate();
	}

	public void setImage(String id,ImagePair ip) {
		String path=PhoneMaster.getFilePathFromId(id, ".bdt");
		File f=new File(path);
		if(f.exists()){
			
			byte[] bs;
			try {
				bs = PhoneMaster.getFileByteArray(f, ip.Seeker, ip.Length);
				InputStream is = new ByteArrayInputStream(bs); 
				BitmapFactory.Options options = new BitmapFactory.Options();
				options.inSampleSize = 1;
				Bitmap bmp=BitmapFactory.decodeStream(is,null, options);
				if(bmp!=null){
					if(mBitmap!=null){
						mBitmap.recycle();
					}

					mBitmap=bmp;
				}else{
					mBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.loading);
					ig.Update(this);
				}
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		}else{
			mBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.loading);
			ig.Update(this);
		}
		UpdateRZ();
		invalidate();
	}
	public Bitmap getImage(){
		return mBitmap;
	}
	public void setImage(Bitmap bitmap) {
		mBitmap=bitmap;
		UpdateRZ();
		invalidate();
	}
	@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		super.onLayout(changed, left, top, right, bottom);
		UpdateRZ();
	}

	public float getZoom() {
		return Zoom;
	}

	public void setZoom(float zoom) {
		
			if (zoom * Zoom >= 1) {
				Zoom *= zoom;
				if (Zoom >= 5/ RecentZoom) {
					Zoom = 5/ RecentZoom;
				}
			} else {
				Zoom = 1;
			}
		
		update();
	}
	public String getPath(String id, String filename) {
		return Environment.getExternalStorageDirectory().getPath()
				+ Configer.DirHead + id + "/" + filename + "x";
	}
	public interface ImageGetter{
		public void Update(View v);
	}
	public boolean IsSide(int x,int y){
		boolean result=false;
		float bw = mBitmap.getWidth();
		float bh = mBitmap.getHeight();
		float tx = x / getZoom() / RecentZoom+Pan.x;
		float ty = y / getZoom() / RecentZoom+Pan.y;
		int DesX = (int) Math.min(mBitmap.getWidth() * RecentZoom
				* getZoom(), getWidth());
		int DesY = (int) Math.min(mBitmap.getHeight() * RecentZoom
				* getZoom(), getHeight());
		int ResX = Math.round(DesX / RecentZoom / getZoom());
		int ResY = Math.round(DesY / RecentZoom / getZoom());
		if (tx + (bw - ResX) / 2 < 0) {
			result=true;
		}
		
		if (ResX + (tx + (bw - ResX) / 2) > bw) {
			result=true;
		}
		return result;
	}
}